package com.alinesno.cloud.gateway.core.dispather;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alinesno.cloud.gateway.core.annotation.HttpService;
import com.alinesno.cloud.gateway.core.context.ApplicationContextProvider;
import com.alinesno.cloud.gateway.core.dispather.annotation.HttpApiRequestMethod;
import com.alinesno.cloud.gateway.core.dispather.annotation.HttpReturnType;
import com.alinesno.cloud.gateway.core.dispather.factory.HttpServiceFactory;
import com.alinesno.cloud.gateway.core.dispather.http.repoonse.ResponseBean;
import com.alinesno.cloud.gateway.core.dispather.http.repoonse.ResultGenerator;
import com.alinesno.cloud.gateway.core.filter.FilterExecutionChain;

/**
 * HTTP请求转发器
 * 
 * @author WeiXiaoJin
 * @since 2019年9月21日 下午3:34:06
 */
@Controller
@RestController
public class HttpDispather implements BaseDispather {

	private static final Logger log = LoggerFactory.getLogger(HttpDispather.class);

	@Autowired
	private FilterExecutionChain filterExecutionChain;

	/**
	 * 处理请求业务
	 * 
	 * @return
	 */
	// @RequestMapping(value = "/api/{uniquePrefix}/{model}/{method}", method = { RequestMethod.GET, RequestMethod.POST })
	@SuppressWarnings("unused")
	@ResponseBody
	@RequestMapping(value = "/proxy/{uniquePrefix}", method = { RequestMethod.GET, RequestMethod.POST })
	public ResponseBean<Object> handler(
			@PathVariable("uniquePrefix") String uniquePrefix ,
			String model,
			
//			@PathVariable("method") String method, 
			
			HttpServletRequest request, 
			HttpServletResponse response) {

		log.debug("requestMethod:{}", uniquePrefix);
	
		if(StringUtils.isEmpty(model)) {
			model = "" ; 
		}
		
		String beanName = model + "httpServiceProxy" ; //  + uniquePrefix ; //  + "_" + model + "_" + method;

		try {
			// 拦截器
			Map<String, Object> returnMap = getParameterMap(request) ;
			InetSocketAddress inetSocketAddress = new InetSocketAddress(request.getRemoteHost(),request.getRemotePort()); 
			filterExecutionChain.doFilter(inetSocketAddress, returnMap , GATEWAY_TYPE_HTTP);

			log.debug("spring bean name = {}", beanName);
			HttpServiceFactory handler = (HttpServiceFactory) ApplicationContextProvider.getBean(beanName);
			HttpService apiAnnotation = handler.getClass().getAnnotation(HttpService.class);

			String apiDesc = apiAnnotation.desc();
			String requestMethodType = request.getMethod(); 
			String requestMethod = apiAnnotation.method().value();
			boolean validate = apiAnnotation.validate();
			HttpReturnType backType = apiAnnotation.back();

			// 判断请求方式
			if (!(HttpApiRequestMethod.HTTP.value()).equals(requestMethod) && !requestMethodType.equalsIgnoreCase(requestMethod)) {
				return ResultGenerator.genFailResult(apiDesc + " , " + REQUEST_METHOD_ERROR);
			}

			Object backObj = handler.handler(uniquePrefix, null , null , request, response , getParameterMap(request));
			if (HttpReturnType.JSON.equals(backType)) { // 返回json

				backObj = JSON.toJSON(backObj);

			} else if (HttpReturnType.XML.equals(backType)) { // 返回xml (采用xstream)

			}

			filterExecutionChain.doResponseFilter(inetSocketAddress, returnMap, backObj , GATEWAY_TYPE_HTTP);

			return ResultGenerator.genSuccessResult(backObj);
		} catch (NoSuchBeanDefinitionException e) {
			log.error("找不到服务类:", e);
			return ResultGenerator.genFailResult(BUSINESS_NOT_USE);
		} catch (IllegalArgumentException e) {
			log.error("系统参数错误:", e);
			return ResultGenerator.genFailResult(e.getMessage());
		}

	}

	/**
	 * 把request转为map
	 * 
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Map<String, Object> getParameterMap(HttpServletRequest request) {
		// 参数Map
		Map<?, ?> properties = request.getParameterMap();
		// 返回值Map
		Map<String, Object> returnMap = new HashMap<String, Object>();
		Iterator<?> entries = properties.entrySet().iterator();

		Map.Entry<String, Object> entry;
		String name = "";
		String value = "";
		Object valueObj = null;
		while (entries.hasNext()) {
			entry = (Map.Entry<String, Object>) entries.next();
			name = (String) entry.getKey();
			valueObj = entry.getValue();
			if (null == valueObj) {
				value = "";
			} else if (valueObj instanceof String[]) {
				String[] values = (String[]) valueObj;
				for (int i = 0; i < values.length; i++) {
					value = values[i] + ",";
				}
				value = value.substring(0, value.length() - 1);
			} else {
				value = valueObj.toString();
			}
			returnMap.put(name, value);
		}
		return returnMap;
	}

}
